package com.ai.module.chat.util;

import com.ai.module.chat.config.advice.exception.BusinessException;
import com.ai.module.chat.common.domain.entitty.book.FileContentGroupEntity;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.platform.commons.util.StringUtils;
import org.mockito.internal.util.io.IOUtil;
import org.springframework.util.FileCopyUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.assertj.core.api.Fail.fail;

/**
 * @author: MrHe
 * @create: 2023-11-17 21:57
 * @description:
 **/
@Slf4j
public class FileUtils {
    // 《斗破苍穹》
    public static Pattern pattern = Pattern.compile("《(.*?)》");
    public static String AUTHOR ="作者";
    @SneakyThrows
    public static File createSaveFile(String realPath) {
        try {
            System.out.println("Real Path: " + realPath);
            // 检查 realPath 是否为 null
            if (realPath == null) {
                throw new IllegalArgumentException("realPath cannot be null");
            }
            File file = new File(realPath);
            file.getParentFile().mkdirs(); // 创建此抽象路径名指定的所有目录
            if (! file.exists()){
                file.createNewFile();
            }
            return file;
        }catch (Exception ex){
            log.error("文件创建异常:ex[{}],message[{}],url[{}]",ex, ex.getMessage(),realPath);
            System.out.println(ex.getMessage());
            ex.printStackTrace();
            throw ex;
        }

    }
    public static void getContentGroupList(File txtFile, Charset charset, List<FileContentGroupEntity> fileList) {
        StringBuilder sb = new StringBuilder();
        int count = 1;
        String fileName = txtFile.getName();
        String author="";
        fileName = txtFile.getName()
                .replace(".txt","")
                .replace(":","")
                .replace("：","");
        if (fileName.contains(AUTHOR)){
            author = fileName.split(AUTHOR)[1];
        }
        Matcher matcher = pattern.matcher(fileName);

        while (matcher.find()) {
            fileName = matcher.group(1); // 获取匹配到的内容
        }
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(txtFile,charset))) {
            String line;
            while ((line = bufferedReader.readLine())  != null) {
                // 处理每一行数据 .....
                sb.append(line);
                String content = sb.toString();
                if (content.length() > 2048 * 1024){
                    FileContentGroupEntity fileContentVo = new FileContentGroupEntity();
                    fileContentVo.setGroupContent(content);
                    fileContentVo.setFileName(fileName);
                    fileContentVo.setSize(sb.toString().length());
                    fileContentVo.setPorosity(count);
                    fileContentVo.setAuthor(author);
                    fileList.add(fileContentVo);
                    sb = new StringBuilder();
                    count++;
                }
            }
            FileContentGroupEntity fileContentVo = new FileContentGroupEntity();
            fileContentVo.setGroupContent(sb.toString());
            fileContentVo.setFileName(fileName);
            fileContentVo.setSize(sb.toString().length());
            fileContentVo.setPorosity(count);
            fileContentVo.setAuthor(author);
            fileList.add(fileContentVo);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage(), e);
        }

    }

    /**
     *
     * @param sourceUrl 要读取的文件路径
     * @return 文件目录下的拆分内容
     */
    public static List<FileContentGroupEntity> contentGroups(String sourceUrl){
        long start = System.currentTimeMillis();
        List<FileContentGroupEntity> contentGroups = new ArrayList<>();
        if (StringUtils.isBlank(sourceUrl)){
            sourceUrl= FileEncodingDetection.BASE_URL;
        }
        try {
            File file = new File(sourceUrl);
            File[] files = file.listFiles();
            for (File f : files) {
                Charset fileCharsetName = FileEncodingDetection.getFileCharsetName(f);
                FileUtils.getContentGroupList(f, fileCharsetName,contentGroups);
            }
        }catch (Exception e){
            e.printStackTrace(); // or log the exception
            fail("Exception occurred: " + e.getMessage());
        }
        log.info("文件目录下的拆分内容 sourceUrl{},耗费时间{},获取数据{}",
                sourceUrl,
                System.currentTimeMillis()-start,
                contentGroups.size());
        return  contentGroups;
    }

    /**
     *
     * @param fileList 文件分类内容
     * @param targetUrl 创建的分类文件内容的链接
     */
    public static void createTargetFile(List<FileContentGroupEntity> fileList, String targetUrl) {
        long start = System.currentTimeMillis();
        fileList.forEach(contentGroup->{
            try {
                //String newFileName = NEW_URL + "/" + contentGroup.getFileName() + contentGroup.getPorosity();
                String realFileName = contentGroup.getFileName() + "_" + contentGroup.getPorosity() + ".txt";
                String realFilePath = String.format("%s\\%s\\%s",targetUrl,contentGroup.getFileName(), realFileName);

                File newFile = new File(realFilePath);
                Path filePath = Paths.get(realFilePath);
                Files.createDirectories(filePath.getParent());
                if (Files.exists(filePath)) {
                    // 文件已存在，可以选择删除或采取其他操作
                    Files.delete(filePath); // 删除文件
                }
                Files.createFile(filePath); // 创建新文件
                IOUtil.writeText(contentGroup.getGroupContent(),newFile);

            }catch (Exception ex){
                ex.printStackTrace();
            }
        });
        log.info("进行文件入库操作,入库地址 {},耗费时间{},入库数据 {}",targetUrl,System.currentTimeMillis()-start,fileList.size());
    }

    public static void writeFileByUrl(String urlString,File file) throws Exception {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        // 检查响应码
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 获取输入流
            InputStream stream = connection.getInputStream();
            FileCopyUtils.copy(stream.readAllBytes(),file);
        } else {
            // 处理错误响应或抛出异常
            throw new BusinessException("GET request failed with response code: " + responseCode);
        }
    }

    /**
     * 图片转Base64字符串
     * @param imageUrl 文件地址
     * @return base64字符串
     */
    public static String convertImageToBase64Str(String imageUrl) {
        ByteArrayOutputStream baos = null;
        try {
            //获取图片类型
            String suffix = imageUrl.substring(imageUrl.lastIndexOf(".") + 1);
            //构建文件
            File imageFile = new File(imageUrl);
            //通过ImageIO把文件读取成BufferedImage对象
            BufferedImage bufferedImage = ImageIO.read(imageFile);
            //构建字节数组输出流
            baos = new ByteArrayOutputStream();
            //写入流
            ImageIO.write(bufferedImage, suffix, baos);
            //通过字节数组流获取字节数组
            byte[] bytes = baos.toByteArray();
            //获取JDK8里的编码器Base64.Encoder转为base64字符
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Base64字符串转图片
     * @param base64String base64字符串
     * @param imageUrl     生产的文件路径
     */
    public static void convertBase64StrToImage(String base64String, String imageUrl) {
        ByteArrayInputStream bais = null;
        try {
            //获取图片类型
            String suffix = imageUrl.substring(imageUrl.lastIndexOf(".") + 1);
            //获取JDK8里的解码器Base64.Decoder,将base64字符串转为字节数组
            byte[] bytes = Base64.getDecoder().decode(base64String);
            //构建字节数组输入流
            bais = new ByteArrayInputStream(bytes);
            //通过ImageIO把字节数组输入流转为BufferedImage
            BufferedImage bufferedImage = ImageIO.read(bais);
            //构建文件
            File imageFile = new File(imageUrl);
            //写入生成文件
            ImageIO.write(bufferedImage, suffix, imageFile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bais != null) {
                    bais.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        System.out.println("----------------------------图片转Base64字符串---------------------------");
        //图片文件路径
        String imageFileName = "C:\\Users\\14550\\Pictures\\sand.jpg";
        //图片转Base64字符串
        String base64Str = convertImageToBase64Str(imageFileName);
        System.out.println(base64Str);

        System.out.println("----------------------------Base64字符串转图片---------------------------");
        //新文件路径
        String newFileName = "C:\\Users\\14550\\Pictures\\sand_test.jpg";
        //Base64字符串转图片
        convertBase64StrToImage(base64Str, newFileName);
        System.out.println("生成的文件的路径是："+newFileName);
    }
}
